//
//  LoginViewModel.swift
//  RxStudy
//
//  Created by TRS-Mobile on 2024/6/6.
//  Copyright © 2024 season. All rights reserved.
//

import Foundation
import RxCocoa
import RxSwift


struct LoginViewModel: ViewModelType {
    struct Input {
        let name: Driver<String>
        let password: Driver<String>
        let rigisetTrigger: Driver<Void>
        let loginTrigger: Driver<Void>
    }
    
    struct Output {
        let pwdEnabled: Driver<Bool>
        let loginEnabled: Driver<Bool>
        let maxName: Driver<String>
        let loginSuccess: Driver<Bool>
    }
    
    private let disposeBag = DisposeBag()
    
    let netProvider: UserAccountService
    let shareInfo = AccountManager.shared
    
    init(netProvider: UserAccountService) {
        self.netProvider = netProvider
    }
    
    func transform(input: Input) -> Output {
        let max = input.name
            .map {
                if $0.count > 11 {
                    return String($0.prefix(11))
                }
                return $0
            }
        
        let pwdE = max
            .map { isMobileNumber($0)}
        
        let passwordE = input.password
            .map { isValidPassword($0) }
        
        let nameAndPwd = Driver.combineLatest(input.name, input.password)
        
        let ls = input.loginTrigger
            .withLatestFrom(nameAndPwd)
//            .throttle(.seconds(1), latest: false)
            .flatMapLatest {
                netProvider
                    .login(name: $0, pwd: $1)
                    .asDriver(onErrorJustReturn: false)
            }
        
        let zip: Single<(CoinRank, Int)> = Single.zip(netProvider.queryUserCoin(), netProvider.queryUserUnreadMessageCount())
        
        ls.asObservable()
            .filter { $0 }
            .flatMapLatest({ _ in
                zip
            })
            .subscribe { (rank, count) in
                shareInfo.myCoinRelay.accept(rank)
                shareInfo.myUnreadMessageCountRelay.accept(count)
            } onError: { _ in
                shareInfo.myCoinRelay.accept(nil)
                shareInfo.myUnreadMessageCountRelay.accept(0)
            }
            .disposed(by: disposeBag)
        
        let loginE = Driver.combineLatest(pwdE, passwordE) {
            $0 && $1
        }
        return Output(pwdEnabled: pwdE,
                      loginEnabled: loginE,
                      maxName: max,
                      loginSuccess: ls)
    }
}

func isMobileNumber(_ num: String) -> Bool {
    return num.count == 11
}

func isValidPassword(_ pwd: String) -> Bool {
    pwd.count > 6
}
